use async_trait::async_trait;
use tokio::sync::mpsc::{UnboundedSender, UnboundedReceiver, unbounded_channel};
use crate::queue::queue_trait::EventQueue;

pub struct SpscQueue<T> {
    sender: UnboundedSender<T>,
    receiver: tokio::sync::Mutex<UnboundedReceiver<T>>,
}

impl<T: Send + 'static> SpscQueue<T> {
    pub fn new() -> Self {
        let (sender, receiver) = unbounded_channel();
        Self {
            sender,
            receiver: tokio::sync::Mutex::new(receiver),
        }
    }
}

#[async_trait]
impl<T: Send + 'static> EventQueue<T> for SpscQueue<T> {
    async fn enqueue(&self, event: T) {
        let _ = self.sender.send(event);
    }

    async fn dequeue(&self) -> Option<T> {
        self.receiver.lock().await.recv().await
    }
}
